﻿using Sgr.Application.Queries;
using Sgr.AuditLogs.Model;
using Sgr.Exceptions;

namespace Sgr.AuditLogs.Services
{
    public class AuditSummaryService : IAuditSummaryService
    {
        private readonly ISgrQueryContext _context;
        private readonly ILogger<AuditSummaryService> _logger;

        public AuditSummaryService(ISgrQueryContext context,
             ILogger<AuditSummaryService> logger)
        {
            _context = context ?? throw new ArgumentNullException(nameof(context));
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
        }

        /// <summary>
        /// 获取指定时间范围内的小时活跃度分布
        /// </summary>
        /// <param name="start">开始时间</param>
        /// <param name="end">结束时间</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>包含24个元素的数组，索引0代表0-1点，索引23代表23-24点的操作总数</returns>
        public async Task<int[]> GetHourlyActivityDistribution(DateTime start, DateTime end, CancellationToken cancellationToken = default)
        {
            if (start >= end)
                throw new BusinessException("开始时间必须小于结束时间。");

            // 直接按小时分组，不需要按日期分组
            var query = _context.Query<LogOperate>()
                .Where(a => a.RequestTime >= start && a.RequestTime < end)
                .GroupBy(a => a.RequestTime.Hour)
                .Select(g => new { Hour = g.Key, Count = g.Count() });

            var hourlyDistribution = await _context.ToListAsync(query, cancellationToken);

            // 初始化24小时数组并填充
            int[] hourlyCounts = new int[24];
            foreach (var item in hourlyDistribution)
            {
                hourlyCounts[item.Hour] = item.Count;
            }

            return hourlyCounts;
        }

        /// <summary>
        /// 获取指定时间范围内的操作统计信息
        /// </summary>
        /// <param name="start">开始时间</param>
        /// <param name="end">结束时间</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>操作统计结果</returns>
        public async Task<OperationStatistics> GetOperationStatistics(DateTime start, DateTime end, CancellationToken cancellationToken = default)
        {
            if (start >= end)
                throw new BusinessException("开始时间必须小于结束时间。");

            try
            {
                // 查询指定时间范围内的操作统计
                var query = _context.Query<LogOperate>()
                    .Where(log => log.RequestTime >= start && log.RequestTime < end)
                    .GroupBy(log => log.Status)
                    .Select(g => new { Status = g.Key, Count = g.Count() });

                var statusGroups = await _context.ToListAsync(query, cancellationToken);

                int totalOperations = 0;
                int failedOperations = 0;

                foreach (var group in statusGroups)
                {
                    totalOperations += group.Count;
                    if (!group.Status) // Status == false 表示失败
                    {
                        failedOperations += group.Count;
                    }
                }

                // 如果没有数据，返回空统计
                return new OperationStatistics
                {
                    TotalOperations = totalOperations,
                    FailedOperations = failedOperations
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取操作统计信息时发生错误：开始时间={Start}，结束时间={End}", start, end);
                throw;
            }
        }
    }
}